/******************************************************************
 * This program was written as part of
 *   Assignment 4
 *   Computer Graphics                                             
 *   Semester 1, 2013
 *   School of Computer Science,
 *   The University of Adelaide
 *                                                                          
 * I declare that all material in this assessment is my own work except where
 * there is clear acknowledgement and reference to the work of others. I have
 * read the University Policy Statement on Plagiarism, Collusion and Related
 * Forms of Cheating:  

 * http://www.adelaide.edu.au/policies/?230

 * I give permission for my assessment work, including my subversion
 * repository, to be reproduced and submitted to academic staff for the
 * purposes of assessment and to be copied, submitted and retained in a form
 * suitable for electronic checking of plagiarism.  
                            
 * Authors:
 *  Terry Moschou    a1208955
 *  Salih Al-Rashid  a1210108
 *  Ben McAleer      a1212203
*******************************************************************/

#include "TerrainGenerator.hpp"
#include <cmath>

#define PI 3.14
#define COLUMNS 64
#define ROWS 64

TerrainGenerator::TerrainGenerator() {

  m_rows = ROWS;
  m_cols = COLUMNS;
  m_terrainArray = new float [ (m_rows+1) * (m_cols+1) ];
  
  addHill(0.3, 25, 25, 15, 0.5);
  addHill(0.5, 11, 8, 7, 1.0);
  addHill(2.0, 5, 40, 10, 2.0);


}

int TerrainGenerator::offset(int horizontal, int vertical) {
  return vertical*(m_cols + 1) + horizontal;
}

void TerrainGenerator::addHill(float h, int x, int z, int radius, float sharpness) {
  
  if(x <= m_cols && x >= 0 && z <= m_rows && z >= 0)
    m_terrainArray[offset(x,z)] += h;

  //at every distance
  for(int i = 1; i < radius; i++) {
    float hh = h*powf(1.0f-i*1.0f/radius,sharpness);
    int xx = 0;
    int zz = -i;
    
    //moving around the diamond
    for(int k = 0; k < i; k++) {
      xx++;
      zz++;
      if(xx <= m_cols && xx >= 0 && zz <= m_rows && zz >= 0)
	m_terrainArray[offset(xx,zz)] += hh;
    }
    for(int k = 0; k < i; k++) {
      xx--;
      zz++;
      if(xx <= m_cols && xx >= 0 && zz <= m_rows && zz >= 0)
	m_terrainArray[offset(xx,zz)] += hh;
    }
    for(int k = 0; k < i; k++) {
      xx++;
      zz--;
      if(xx <= m_cols && xx >= 0 && zz <= m_rows && zz >= 0)
	m_terrainArray[offset(xx,zz)] += hh;
    }
    for(int k = 0; k < i; k++) {
      xx++;
      zz--;
      if(xx <= m_cols && xx >= 0 && zz <= m_rows && zz >= 0)
	m_terrainArray[offset(xx,zz)] += hh;
    }
  }
}